home *** CD-ROM | disk | FTP | other *** search
Text File | 1978-01-22 | 61.1 KB | 1,512 lines |
- CHAPTER 10
- Mathematical functions
-
- Summary
-
- PI, EXP, LN, SIN, COS, TAN, ASN, ACS, ATN
-
- This chapter deals with the mathematics that the ZX Spectrum
- can handle. Quite possibly you will never have to use any of
- this at all, so if you find it too heavy going, don't be
- afraid of skipping it. It covers the operation (raising to a
- power), the functions EXP and LN, and the trigonometrical
- functions SIN, COS, TAN and their inverses ASN, ACS, and ATN.
-
- ^ and EXP
-
- You can raise one number to the power of another - that means
- 'multiply the first number by itself the second number of
- times'. This is normally shown by writing the second number
- just above and to the right of the first number; but obviously
- this would be difficult on a computer so we use the symbol
- instead. For example, the powers of 2 are
-
- 21=2
- 22=2*2=4 (2 squared)
- 23=2*2*2=8 (2 cubed)
- 24=2*2*2*2=16 (2 to the power four)
-
- Thus at its most elementary level, 'ab' means 'a multiplied
- by itself b times', but obviously this only makes sense if b is
- a positive whole number. To find a definition that works for
- other values of b, we consider the rule
-
- a(b+c) = ab*ac
-
- (Notice that we give a higher priority than * and / so that
- when there are several operations in one expression, the s are
- evaluated before the s and /s. ) You should not need much
- convincing that this works when b and c are both positive whole
- numbers; but if we decide that we want it to work even when the
- y are not, then we find ourselves compelled to accept that
-
- a0 = 1
- a(-b) = 1/ab
- a(1/b) = the bth root of a, which is to say, the number that
- you have to multiply by itself b times to get a
-
- and
-
- a(b*c)=(ab)c
-
- If you have never seen any of this before then don't try to
- remember it straight away; just remember that
-
- at (-1)=1/a
-
- and
-
- at (1/2)=SQR a
-
- and maybe when you are familiar with these the rest will begin
- to make sense.
-
-
- Experiment with all this by trying this program:
-
- 10 INPUT a,b,c
- 20 PRINT a(b+c),ab*ac
- 30 GO TO 14
-
- Of course, if the rule we gave earlier is true, then each
- time round the two numbers that the computer prints out will be
- equal. (Note - because of the way the computer works out t, the
- number on the left - a in this case - must never be negative.)
-
- A rather typical example of what this function can be used
- for is that of compound interest. Suppose you keep some of your
- money in a building society and they give 15% interest per
- year. Then after one year you will have not just the 100% that
- you had anyway, but also the 15% interest that the building
- society have given you, making altogether 115% of what you had
- originally. To put it another way, you have multiplied your sum
- of money by 1.15, and this is true however much you had there
- in the first place. After another year, the same will have
- happened again, so that you will then have 1.15*1.15=1.1512=1
- .3225 times your original sum of money. In general, after y
- years, you will have 1.15y times what you started out with.
-
- If you try this command
-
- FOR y=0 TO 198: PRINT y,10*1.15Y: NEXT y
-
- you will see that even starting off from just ú10, it all
- mounts up quite quickly, and what is more, it gets faster and
- faster as time goes on. (Although even so, you might still find
- that it doesn't keep up with inflation.)
-
- This sort of behaviour, where after a fixed interval of time
- some quantity multiplies itself by a fixed proportion, is
- called exponential growth, and it is calculated by raising a
- fixed number to the power of the time.
-
- Suppose you did this:
-
- 10 DEF FN a(x)=ax
-
- Here, a is more or less fixed, by LET statements: its value
- will correspond to the interest rate, which changes only every
- so often.
-
- There is a certain value for a that makes the function FN a
- look especially pretty to the trained eye of a mathematician:
- and this value is called e. The ZX Spectrum has a function
- called EXP defined by
-
- EXP x=ex
-
- Unfortunately, e itself is not an especially pretty number:
- it is an infinite non-recurring decimal. You can see its first
- few decimal places by doing
-
- PRINT EXP 1
-
- because EXP 1 = e1 = e. Of course, this is just an
- approximation. You can never write down e exactly.
-
- LN
- The inverse of an exponential function is a logarithmic
- function: the logarithm (to base a) of a number x is the power
- to which you have to raise a to get the number x, and it is
- written logax. Thus by definition alogax=x; and it is also true
- that log (ax)=x.
-
- You may well already know how to use base 10 logarithms for
- doing multiplications; these are called common logarithms. The
- ZX Spectrum has a function LN which calculates logarithms to
- the base e; these are called natural logarithms. To calculate
- logarithms to any other base, you must divide the natural
- logarithm by the natural logarithm of the base:
-
- logax = LN x/ LN a
-
- PI
- Given any circle, you can find its perimeter (the distance
- round its edge; often called its circumference) by multiplying
- its diameter (width) by a number called p. (p is a Greek p, and
- it is used because it stands for perimeter.
- Its name is pi.)
-
- Like e, p is an infinite non-recurring decimal; it starts off
- as 3.141592653589....The word PI on the Spectrum (extended
- mode, then M) is taken as standing for this number - try PRINT
- PI.
-
- SIN, COS and TAN; ASN, ACS and ATN
- The trigonometrical functions measure what happens when a
- point moves round a circle. Here is a circle of radius 1 (1
- what? It doesn't matter, as long as we keep to the same unit
- all the way through. There is nothing to stop you inventing a
- new unit of your own for every circle that you happen to be
- interested in) and a point moving round it. The point started
- at the 3 o'clock position, and then moved round in an anti-
- clockwise direction.
-
-
- We have also drawn in two lines called axes through the
- centre of the circle. The one through 9 o'clock and 3 o'clock
- is called the x-axis, and the one through 6 o'clock and 12
- o'clock is called the y-axis.
-
- To specify where the point is, you say how far it has moved
- round the circle from its 3 o'clock starting position: let us
- call this distance a. We know that the circumference of the
- circle is 2p (because its radius is 1 and its diameter is thus
- 2): so when it has moved a quarter of the way round the circle,
- a=p/2; when it has moved halfway round, a=p; and when it has
- moved the whole way round, a=2p.
-
- Given the curved distance round the edge, a, two other
- distances you might like to know are how far the point is to
- the right of the y-axis, and how far it is above the x-axis.
- These are called, respectively, the cosine and sine of a. The
- functions COS and SIN on the computer will calculate these.
-
- F9Vú/(PBrush0 0 341 3298BM8>(UI8Q;%rrl
-
-
-
- Note that if the point goes to the left of the y-axis, then
- the cosine becomes negative; and if the point goes below the x-
- axis, the sine becomes negative.
-
- Another property is that once a has got up to 2p, the point
- is back where it started and the sine and cosine start taking
- the same values all over again
- :
-
- SIN (a+2*PI) = SIN a
- COS (a+2*PI) = COS a
-
- The tangent of a is defined to be the sine divided by the
- cosine; the corresponding function on the computer is called
- TAN.
-
- Sometimes we need to work these functions out in reverse,
- finding the value of a that has given sine, cosine or tangent.
- The functions to do this are called arcsine (ASN on the
- computer), arccosine (ACS) and arctangent (ATN).
-
- In the diagram of the point moving round the circle, look at
- the radius joining the centre to the point. You should be able
- to see that the distance we have called a, the distance that
- the point has moved round the edge of the circle, is a way of
- measuring the angle through which the radius has moved away
- from the x-axis. When a=p/2, the angle is 90 degrees; when a=p
- the angle is 180 degrees; and so round to when a=2p, and the
- angle is 360 degrees. You might just as well forget about
- degrees, and measure the angle in terms of a alone: we say then
- that we are measuring the angle in radians. Thus p/2 radians=
- 90 degrees and so on.
-
- You must always remember that on the ZX Spectrum SIN, COS and
- so on use radians and not degrees. To convert degrees to
- radians, divide by 180 and multiply by p; to convert back from
- radians to degrees, you divide by p and multiply by 180.
-
-
-
- CHAPTER 11
- Random numbers
-
- Summary
-
- RANDOMIZE
- RND
-
- This chapter deals with the function RND and the keyword
- RANDOMIZE. They are both used in connection with random
- numbers, so you must be careful not to get them mixed up. They
- are both on the same key (T); RANDOMIZE has had to be
- abbreviated to RAND.
-
- In some ways RND is like a function: it does calculations and
- produces a result. It is unusual in that it does not need an
- argument.
-
- Each time you use it, its result is a new random number
- between 0 and 1. (Sometimes it can take the value 0, but never
- 1.)
-
- Try
-
- 10 PRINT RND
- 20 GO TO 10
-
- to see how the answer varies. Can you detect any pattern7 You
- shouldn't be able to; 'random' means that there is no pattern.
-
- Actually, RND is not truly random, because it follows a fixed
- sequence of 65536 numbers. However, these are so thoroughly
- jumbled up that there are at least no obvious patterns and we
- say that RND is pseudo-random.
-
- RND gives a random number between 0 and 1, but you can easily
- get random numbers in other ranges. For instance, 5*RND is
- between 0 and 5, and 1.3+0.7*RND is between 1.3 and 2. To get
- whole numbers, use INT (remembering that INT always rounds
- down) as in 1 +INT (RND*6), which we shall use in a program to
- simulate dice. RND*6 is in the range 0 to 6, but since it never
- actually reach es 6, INT (RND*6) is 0,1,2,3,4 or 5.
-
- Here is the program:
-
- 10 REM dice throwing program
- 20 CLS
- 30 FOR n=1 TO 2
- 40 PRINT 1+1NT (RND*6);" ";
- 50 NEXT n
- 60 INPUT a$: GO TO 20
-
- Press ENTER each time you want to throw the dice.
-
- The RANDOMIZE statement is used to make RND start off at a
- definite place in its sequence of numbers, as you can see with
- this program:
-
- 10 RANDOMIZE 1
- 20 FOR n=1 TO 5: PRINT RND ,: NEXT n
- 30 PRINT: GO TO 10
-
- After each execution of RANDOMIZE 1, the RND sequence starts
- off again with 0.0022735596. You can use other numbers between
- 1 and 65535 in the RANDOMIZE statement to start the RND
- sequence off at different places.
-
- If you had a program with RND in it and it also had some
- mistakes that you had not found, then it would help to use
- RANDOMIZE like this so that the program behaved the same way
- each time you ran it.
-
- RANDOMIZE on its own (and RANDOMIZE 0 has the same effect) is
- different, because it really does randomize RND - you can see
- this in the next program.
-
- 10 RANDOMIZE
- 20 PRINT RND: GO TO 10
-
- The sequence you get here is not very random, because
- RANDOMIZE uses the time since the computer was switched on.
- Since this has gone up by the same amount each time RANDOMIZE
- is executed, the next RND does more or less the same. You
- would get better randomness by replacing GO TO 10 by GO TO 20.
-
- Note: Most dialects of BASIC use RND and RANDOMIZE to produce
- random numbers, but not all use them in the same way.
-
- Here is a program to toss coins and count the numbers of
- heads and tails.
-
- 10 LET heads=0: LET tails=0
- 20 LET coin=lNT (RND*2)
- 30 IF coin=3 THEN LET heads=heads+1
- 40 IF coin=1 THEN LET tails=tails+1
- 50 PRINT heads;",";tails,
- 60 IF tails<>6 THEN PRINT heads/tails;
- 70 PRINT: GO TO 20
-
- The ratio of heads to tails should become approximately 1 if
- you go on long enough, because in the long run you expect
- approximately equal numbers of heads and tails.
-
- Exercises
-
- 1. Test this rule:
- Suppose you choose a number between 1 and 872 and type
-
- RANDOMIZE your number
-
- Then the next value of RND will be
-
- (75*(your number+1) -1) /65536
-
- 2. (For mathematicians only.)
- Let p be a (large) prime, and let a be a primitive root
- modulo p. Then if bi is the residue of ai modulo p (l ú bi ú p-
- l ), the sequence
-
- bi -1
- p-1
-
- is a cyclical sequence of p-1 distinct numbers in the range 0
- to 1 (excluding 1). By choosing a suitably, these can be made
- to look fairly random.
-
- 65537 is a Fermat prime, 2l6+1. Because the multiplicative
- group of non-zero residues modulo 65537 has a power of 2 as its
- order, a residue is a primitive root if and only if it is not a
- quadratic residue. Use Gauss' law of quadratic reciprocity to
- show that 75 is a primitive root modulo 65537.
-
- The ZX Spectrum uses p=65537 and a=75, and stores some bi-l
- in memory. RND entails replacing bi-1 in memory by bi+1 -1, and
- yielding the result (bi+1-l) (p-l). RANDOMIZE n (with
- 1únú65535) makes bi equal to n+1.
-
- RND is approximately uniformly distributed over the range 0
- to 1.
-
-
-
- CHAPTER 12
- Arrays
-
- Summary
-
- Arrays (the way the ZX Spectrum handles string arrays is
- slightly non-standard).
- DIM . . .
-
- Suppose you have a list of numbers, for instance the marks of
- ten people in a class. To store them in the computer you could
- set up a single variable for each person. But you would find
- them very awkward. You might decide to call the variable Bloggs
- 1, Bloggs 2, and so on up to Bloggs 10, but the program to set
- up these ten numbers would be rather long and boring to type
- in.
-
- How much nicer it would be if you could type this:
-
- 5 REM this program will not work
- 10 FOR n=1 TO 10
- 20 READ Bloggs n
- 30 NEXT n
- 40 DATA 10,2,5,19,16,3,11,1,0,6
-
- Well you can't.
-
- However, there is a mechanism by which you can apply this
- idea, and it uses arrays. An array is a set of variables, its
- elements, all with the same name , and distinguished only by a
- number (the subscript) written in brackets after the name. In
- our example the name could be b (like control variables of FOR
- - NEXT loops, the name of an array must be a single letter),
- and the ten variables would then be b(l), b(2), and so on up to
- b(l0).
-
- The elements of an array are called subscripted variables, as
- opposed to the simple variables that you are already familiar
- with.
-
- Before you can use an array, you must reserve some space for
- it inside the computer, and you do this using a DIM (for
- dimension) statement.
-
- DIM b(10)
-
- sets up an array called b with dimension 10 (i.e. there are 10
- subscripted variables b(1),...,b(10)) and initializes the 10
- values to 0. It also deletes any array called b that existed
- previously. (But not a simple variable. An array and a simple
- numerical variable with the same name can coexist, and there
- shouldn't be any confusion between them because the array
- variable always has a subscript).
-
- The subscript can be an arbitrary numerical expression, so now
- you can write
-
-
- 10 FOR n=1 TO 10
- 20 READ b(n)
- 30 NEXT n
- 40 DATA 10,2,5,19,16,3,11,1,0,6
-
- You can also set up arrays with more than one dimension. In a
- two dimension al array you need two numbers to specify one of
- the elements - rather like the line and column numbers to
- specify a character position on the television screen - so it
- has the form of a table. Alternatively, if you imagine the line
- and column numbers (two dimensions) as referring to a printed
- page, you could have an extra dimension for the page numbers.
- Of course, we are talking about numeric arrays; so the elements
- would not be printed characters as in a book, but numbers.
- Think of the elements of a three-dimensional array v as being
- specified by v (page number, line number, column number).
-
- For example, to set up a two-dimensional array c with
- dimensions 3 and 6, you use a DIM statement
-
- DIM c(3,6)
-
- This then gives you 3*6=18 subscripted variables
-
- c(1 ,1),c(1 ,2), . . .,c(1,6)
- c(2, 1 ),c(2,2), . . .,c(2,6)
- c(3, 1 ),c(3,2), . . .,c(3,6)
-
- The same principle works for any number of dimensions.
-
- Although you can have a number and an array with the same
- name, you cannot have two arrays with the same name, even if
- they have different numbers of dimensions.
-
- There are also string arrays. The strings in an array differ
- from simple strings in that they are of fixed length and
- assignment to them is always Procrustean - chopped off or
- padded with spaces. Another way of thinking of them is as
- arrays (with one extra dimension) of single characters. The
- name of a string array is a single letter followed by $, and a
- string array and a simple string variable cannot have the same
- name (unlike the case for numbers).
-
- Suppose then, that you want an array a$ of five strings. You
- must decide how long these strings are to be - let us suppose
- that 10 characters each is long enough. You then say
-
- DIM a$(5,10) (type this in)
-
- This sets up a 5*10 array of characters, but you can also
- think of each row as being a string:
-
- a$(1)=a$(1,1) a$(1,2) . . . a$(1,10)
- a$(2)=a$(2,1) a$(2,2) . . . a$(2,10)
- : : : :
- a$(5)=a$(5,1) a$(5,2) . . . a$(5,10)
-
- If you give the same number of subscripts (two in this case)
- as there were dimensions in the DIM statement, then you get a
- single character; but if you miss the last one out, then you
- get a fixed length string. So, for instance, A$(2,7) is the 7th
- character in the string A$(2); using the slicing notation, we
- could also write this as A$(2)(7). Now type
-
- LET a$(2)="1234567890"
- and
- PRINT a$(2),a$(2,7)
-
- For the last subscript (the one you can miss out), you can
- also have a slicer, so that for instance
-
- a$(2,4 TO 8)=a$(2)(4 TO 8)="45678"
-
- Remember:
-
- In a string array, all the strings have the same, fixed length.
- The DIM statement has an extra number (the last one) to specify
- this length. When you write down a subscripted variable for a
- string array, you can put in an extra number, or a slicer, to
- correspond with the extra number in the DIM statement. You can
- have string arrays with no dimensions. Type
-
- DIM a$(10)
-
- and you will find that a$ behaves just like a string variable,
- except that it always has length 10, and assignment to it is
- always procrustean.
-
- Exercises
-
- 1. Use READ and DATA statements to set up an array m$ of twelve
- strings in which m$(n) is the name of the nth month. (Hint: the
- DIM statement will be DIM m$(12,9). Test it by printing out all
- the mS(n) (use a loop).
-
- Type
-
- PRINT "now is the month of ";m$(5);"ing";" when merry
- lads are playin
- g"
-
- What can you do about all those spaces?
-
-
-
- CHAPTER 13
- Conditions
-
- Summary
-
- AND, OR
- NOT
-
- We saw in Chapter 3 how an IF statement takes the form
-
- IF condition THEN . . .
-
- The conditions there were the relations (=, <, >, <=, >= and
- <>), which compare two numbers or two strings. You can also
- combine several of these, using the logical operations, AND,
- OR and NOT.
-
- One relation AND another relation is true whenever both
- relations are true, so you could have a line like:
-
- IF a$="yes" AND x>0 THEN PRINT x
-
- in which x only gets printed if a$=''yes" and x>0. The BASIC
- here is so close to English that it hardly seems worth
- spelling out the:details. As in English, you can join lots of
- relations together with AND, and then the whole lot is true if
- all the individual relations are.
-
- One relation OR another is true whenever at least one of the
- two relations is true. (Remember that it is still true if both
- the relations are true; this is something that English doesn't
- always imply.)
-
- The NOT relationship turns things upside down. The NOT
- relation is true whenever the relation is false, and false
- whenever it is true!
-
- Logical expressions can be made with relations and AND, OR
- and NOT, just as numerical expressions can be made with
- numbers and +, - and so on; you can even put them in brackets
- if necessary. They have priorities in the same way as the usual
- operations +, -, *, / and , do: OR has the lowest priority,
- then AND, then NOT, then the relations, and the usual
- operations.
-
- NOT is really a function, with an argument and a result, but
- its priority is much lower than that of other functions.
- Therefore its argument does not need brackets unless it
- contains AND or OR (or both). NOT a=b means the same as
- NOT (a=b) (and the same as a<>b, of course).
-
- <> is the negation of = in the sense that it is true if, and
- only if, = is false. In other words,
-
- a<>b is the same as NOT a=b
-
- and also
-
- NOT a<>b is the same as a=b
-
- Persuade yourself that >= and <= are the negations of < and >
- respectively: thus you can always get rid of NOT from in front
- of a relation by changing the relation.
-
- Also,
-
- NOT (a first logical expression AND a second)
-
- is the same as
-
- NOT (the first) OR NOT (the second)
-
- and
-
- NOT (a first logical expression OR a second)
-
- is the same as
-
- NOT (the first) AND NOT (the second).
-
- Using this you can work NOTs through brackets until
- eventually they are all applied to relations, and then you can
- get rid of them. Logically speaking, NOT is unnecessary,
- although you might still find that using it makes a program
- clearer.
-
- The following section is quite complicated, and can be
- skipped by the faint hearted!
-
- Try
-
- PRINT 1=2,1 < >2
-
- which you might expect to give a syntax error. In fact, as far
- as the computer is concerned, there is no such thing as a
- logical value: instead it uses ordinary numbers, subject to a
- few rules.
-
- (i) =, <, >, <=, >= and <> all give numeric results: 1 for
- true, and 0 for false. Thus the PRINT command above printed 0
- for '1=2', which is false, and 1 for '1<>2', which is true.
-
- (ii) In
-
- IF condition THEN . . .
-
- the condition can be actually any numeric expression. If its
- value is 0, then it counts as false, and any other value
- including the value of 1 that a true relation gives) counts as
- true. Thus the IF statement means exactly the same as
-
- IF condition <>0 THEN . . .
-
- (iii) AND, OR and NOT are also number-valued operations.
-
- x AND y has the value {x if y is true (non-zero)
- {0 (false), if y is false (zero)
-
- x OR y has the value {1 (true), if y is true (non zero)
- {x, if y is false (zero)
-
- NOT x has the value {0 (false), if x is true (non-zero)
- {1 (true), if x is false (zero)
-
-
- (Notice that 'true' means 'non-zero' when we're checking a
- given value, but it means '1' when we're producing a new one.)
-
- Read through the chapter again in the light of this
- revelation, making sure that it all works.
-
- In the expressions x AND y, x OR y and NOT x, x and y will
- usually take the values 0 and 1 for false and true. Work out
- the ten different combinations (four for AND, four for OR and
- two for NOT) and check that they do what the chapter leads you
- to expect them to do.
-
- Try this program:
-
- 10 INPUT a
- 20 INPUT b
- 30 PRINT (a AND a>=b)+(b AND a<b)
- 40 GO TO 10
-
- Each time it prints the larger of the two numbers a and b.
- Convince yourself that you can think of
-
- x AND y
-
- as meaning
-
- x if y (else the result is 0)
-
- and of
-
- x OR y
-
- as meaning
-
- x unless y (in which case the result is 1)
-
- An expression using AND or OR like this is called a
- conditional expression. An example using OR could be
-
- LET total price=price less tax*(1.15 OR
- v$="zero rated")
-
- Notice how AND tends to go with addition (because its default
- value is 0), and OR tends to go with multiplication (because
- its default value is 1).
-
- You can also make string valued conditional expressions, but
- only using AND.
-
-
- x$ AND y has the value {x$ if y is non-zero
- {"" if y is zero
-
- so it means x$ if y (else the empty string).
-
- Try this program, which inputs two strings and puts them in
- alphabetical order.
-
- 10 INPUT "type in two strings"'a$,b$
- 20 IF a$>b$ THEN LET c$=a$: LET a$=b$: LET b$=c$
- 30 PRINT a$;" ";("<" AND a$<b$)+("=" AND a$=b$);" ";b$
- 40 GO TO 10
-
- Exercise
-
- 1. BASIC can sometimes work along different lines from English.
- Consider, for instance, the English clause 'If a doesn't equal
- b or c'. How would you write this in BASIC? The answer is not
- IF A<>B OR C
- nor is it
- IF A<>B OR A<>C
-
-
-
- CHAPTER 14
- The Character Set
-
- Summary
-
- CODE, CHR$
- POKE, PEEK
- USR
- BIN
-
- The letters, digits, punctuation marks and so on that can
- appear in strings are called characters, and they make up the
- alphabet, or character set, that the ZX Spectrum uses. Most of
- these characters are single symbols, but there are some more,
- called tokens, that represent whole words, such as PRINT, STOP
- , <> and so on.
-
- There are 256 characters, and each one has a code between 0
- and 255. There is a complete list of them in Appendix A. To
- convert between codes and characters, there are two functions,
- CODE and CHR$.
-
- CODE is applied to a string, and gives the code of the first
- character in the string (or 0 if the string is empty).
-
- CHR$ is applied to a number, and gives the single character
- string whose code is that number.
-
- This program prints out the entire character set:
-
- 10 FOR a=32 TO 255: PRINT CHRS a;: NEXT a
-
- At the top you can see a space, 15 symbols and punctuation
- marks, the ten digits, seven more symbols, the capital letters,
- six more symbols, the lower case letters and five more symbols.
- These are all (except ú and ) taken from a widely-used set of
- characters known as ASCII (standing for American Standard
- Codes for Information Interchange); ASCII also assigns numeric
- codes to these characters, and these are the codes that the ZX
- Spectrum uses.
-
- The rest of the characters are not part of ASCII, and are
- peculiar to the ZX Spectrum. First amongst them are a space and
- 15 patterns of black and white blobs. These are called the
- graphics symbols and can be used for drawing pictures. You can
- enter these from the keyboard, using what is called graphics
- mode. If you press GRAPHICS (CAPS SHIFT with 9) then the cursor
- will change to
- G. Now the keys for the digits 1 to 8 will give the graphics
- symbols: on their own they give the symbols drawn on the keys;
- and with either shift pressed they give the same symbol but
- inverted, i.e. black becomes white, and vice versa.
-
- Regardless of shifts, digit 9 takes you back to normal (L)
- mode and digit 0
- is DELETE.
-
-
- After the graphics symbols, you will see what appears to be
- another copy of the alphabet from A to U. These are characters
- that you can redefine yourself. although when the machine is
- first switched on they are set as letters - they are called
- user-defined graphics. You can type these in from the keyboard
- by going into graphics mode, and then using the letters keys
- from A to U.
-
- To define a new character for yourself, follow this recipe -
- it defines a character to show p.
-
- (i) Work out what the character looks like. Each character has
- an 8x8 square of dots, each of which can show either the paper
- colour or the ink colour (see the introductory booklet). You'd
- draw a diagram something like this, with black squares for the
- ink colour:
-
-
- We've left a 1 square margin round the edge because the other
- letters all have one (except for lower case letters with tails,
- where the tail goes right down to the bottom).
-
- (ii) Work out which user-defined graphic is to show n- let's
- say the one corresponding to P, so that if you press P in
- graphics mode you get p.
-
- (iii) Store the new pattern. Each user-defined graphic has its
- pattern stored as eight numbers, one for each row. You can
- write each of these numbers as BIN followed by eight 0's or 1
- 's - 0 for paper, 1 for ink - so that the eight numbers for
- our p character are
-
- BIN 00000000
- BIN 00000000
- BIN 00000010
- BIN 00111100
- BIN 01010100
- BIN 00010100
- BIN 00010100
- BIN 00000000
-
- (If you know about binary numbers, then it should help you to
- know that BIN is used to write a number in binary instead of
- the usual decimal.)
-
- These eight numbers are stored in memory, in eight places,
- each of which has an address. The address of the first byte, or
- group of eight digits, is USR "P" (P because that is what we
- chose in (ii)), that of the second is USR "P" +1, and so on up
- to the eighth, which has address USR "P"+7.
-
- USR here is a function to convert a string argument into the
- address of the first byte in memory for the corresponding
- user-defined graphic. The string argument must be a single
- character which can be either the user-defined graphic itself
- or the corresponding letter (in upper or lower case). There is
- another use for USR, when its argument is a number, which will
- be dealt with.
-
- Even if you don't understand this, the following program will
- do it for you
- :
-
- 10 FOR n=0 TO 7
- 20 INPUT row: POKE USR "P"+n,row
- 30 NEXT n
-
- It will stop for INPUT data eight times to allow you to type
- in the eight BIN numbers above - type them in the right order,
- starting with the top row.
-
- The POKE statement stores a number directly in memory
- location, bypassing the mechanisms normally used by the BASIC.
- The opposite of POKE is PEEK, and this allows us to look at the
- contents of a memory location although it does not actually
- alter the contents of that location. They will be dealt with
- properly in Chapter 24.
-
- After the user-defined graphics come the tokens.
-
- You will have noticed that we have not printed out the first
- 32 characters, with codes 0 to 31. These are control
- characters. They don't produce anything printable, but have
- some less tangible effect on the television, or they are used
- for controlling something other than the television, and the
- television prints ? to show that it doesn't understand them.
- They are described more fully in Appendix A.
-
- Three that the television uses are those with codes 6, 8 and
- 13; on the whole, CHR$ 8 is the only one you are likely to find
- useful.
-
- CHR$ 6 prints spaces in exactly the same way as a comma does
- in a PRINT statement for instance
-
- PRINT 1; CHR$ 6;2
-
- does the same as
-
- PRINT 1,2
-
- Obviously this is not a very clear way of using it. A more
- subtle way is to
- say
-
- LET a$="1"+CHR$ 6+"2"
- PRINT a$
-
- CHR$ 8 is 'backspace': it moves the print position back one
- place - try
-
- PRINT "1234"; CHR$ 8;"5"
-
- which prints up 1235
-
- CHR$ 13 is 'newline': it moves the print position on to the
- beginning of the next line.
-
- The television also uses those with codes 16 to 23; these are
- explained in Chapters 15 and 16. All the control characters are
- listed in Appendix A.
-
- Using the codes for the characters we can extend the concept
- of 'alphabetical ordering' to cover strings containing any
- characters, not just letters. If instead of thinking in terms
- of the usual alphabet of 26 letters we use the extended
- alphabet of 256 characters, in the same order as their codes,
- then the principle is exactly the same. For instance, these
- strings are in their ZX Spectrum alphabetical order. (Notice
- the rather odd feature that lower case letters come after all
- the capitals: so "a" comes after "Z"; also, spaces matter.)
-
- CHR$ 3+"ZOOLOGICAL GARDENS"
- CHR$ 8+"AARDVARK HUNTING"
- "AAAARGH!"
- "(Parenthetical remark)"
- "100"
- "129.95 inc. VAT"
- "AASVOGEL"
- "Aardvark"
- "PRINT"
- "Zoo"
- "[interpolationl"
- "aardvark"
- "aasvogel"
- "zoo"
- "zoology
-
- Here is the rule for finding out which order two strings come
- in. First, compare the first characters. If they are different,
- then one of them has its code less than the other, and the
- string it came from is the earlier (lesser) of the two strings.
- If they are the same, then go on to compare the next
- characters. If in this process one of the strings runs out
- before the other, then that string is the earlier, otherwise
- they must be equal.
-
- The relations =, <, >, <=, >= and <> are used for strings as
- well as for numbers: < means 'comes before' and > means 'comes
- after', so that
-
- "AA man"<"AARDVARK"
- "AARDVARK">"AA man"
-
- are both true.
-
- <= and >= work the same way as they do for numbers, so that
-
- "The same string"<="The same string"
-
- is true, but
-
- "The same string"<"The same string"
-
- is false.
-
- Experiment on all this using the program here, which inputs
- two strings and puts them in order.
-
- 10 INPUT "Type in two strings:", a$, b$
- 20 IF a$>b$ THEN LET c$=a$: LET a$=b$: LET b$=c$
- 30 PRINT a$;" ";
- 40 IF a$<b$ THEN PRINT "<";: GO TO 60
- 50 PRINT "="
- 60 PRINT " ";b$
- 70 GO TO 10
-
- Note how we have to introduce c$ in line 20 when we swap over
- a$ and b$,
-
- LET a$=b$: LET b$=a$
-
- would not have the desired effect.
-
- This program sets up user-defined graphics to show chess
- pieces:
-
- P for pawn
- R for rook
- N for knight
- B for bishop
- K for king
- Q for queen
-
- Chess pieces:
-
- 5 LET b=BIN 01111100: LET c=BIN 00111000: LET d=BIN
- 00010000
- 10 FOR n=1 TO 6: READ p$: REM 6 pieces
- 20 FOR f=0 TO 7: REM read piece into 8 bytes
- 30 READ a: POKE USR p$+f,a
- 40 NEXT f
- 50 NEXT n
- 100 REM bishop
- 110 DATA "b",0,d, BIN 00101000,BIN 01000100
- 120 DATA BIN 01101100,c,b,0
- 130 REM king
- 140 DATA "k",0,d,c,d
- 150 DATA c, BIN 01000100,c,0
- 160 REM rook
- 170 DATA "r",0, BIN 01010100,b,c
- 180 DATA c,b,b,0
- 190 REM queen
- 200 DATA "q",0, BIN 01010100, BIN 00101000,d
- 210 DATA BIN 01101100,b,b,0
- 220 REM pawn
- 230 DATA "p",0,0,d,c
- 240 DATA c,d,b,0
- 250 REM knight
- 260 DATA "n",0,d,c, BIN 01111000
- 270 DATA BIN 00011000,c,b,0
-
- Note that 0 can be used instead of BIN 00000000.
-
- When you have run the program, look at the pieces by going
- into graphics mode.
-
- Exercises
-
- 1. Imagine the space for one symbol divided up into four
- quarters like a Battenburg cake. Then if each quarter can be
- either black or white, there are 2x2x2x2=16 possibilities. Find
- them all in the character set.
-
- 2. Run this program:
-
- 10 INPUT a
- 20 PRINT CHR$ a;
- 30 GO TO 10
-
- If you experiment with it, you'll find that CHR$ a is rounded
- to the nearest whole number; and if a is not in the range 0 to
- 255 then the program stops with error report B integer out of
- range.
-
- 3. Which of these two is the lesser?
-
- "EVIL"
- "evil"
-
- 4. Work out how to modify the program to set up user-defined
- graphics so that it uses READ and DATA statements instead of
- the INPUT statement.
-
-
-
- CHAPTER 15
- More about PRINT and INPUT
-
- Summary
-
- CLS
- PRINT items: nothing at all
- Expressions (numeric or string type): TAB numeric
- expression, AT numeric
- expression, numeric expression
- PRINT separators: ,; '
- INPUT items: variables (numeric or string type)
- LINE string variable
- Any PRINT item not beginning with a letter. (Tokens are
- not considered a
- s beginning with a letter.)
- Scrolling.
- SCREEN$
-
- You have already seen PRINT used quite a lot, so you will
- have a rough idea of how it is used. Expressions whose values
- are printed are called PRINT items, and they are separated by
- commas or semicolons, which are called PRINT separators. A
- PRINT item can also be nothing at all, which is a way of
- explaining what happens when you use two commas in a row.
-
- There are two more kinds of PRINT items, which are used to
- tell the computer not what, but where to print. For example
- PRINT AT 11,16;"*" prints a star in the middle of the screen.
-
- AT line, column
-
- moves the PRINT position (the place where the next item is to
- be printed) to the line and column specified. Lines are
- numbered from 0 (at the top) to 21, and columns from 0 (on the
- left) to 31.
-
- SCREEN$ is the reverse function to PRINT AT, and will tell
- you (within limits) what character is at a particular position
- on the screen. It uses line and column numbers in the same way
- as PRINT AT, but enclosed in brackets: for instance
-
- PRINT SCREEN$ (11,16)
-
- will retrieve the star you printed in the paragraph above.
-
- Characters taken from tokens print normally, as single
- characters, and spaces return as spaces. Lines drawn by PLOT,
- DRAW or CIRCLE, user-defined characters and graphics characters
- return as a null (empty) string, however. The same applies if
- OVER has been used to create a composite character.
-
- TAB column
-
- prints enough spaces to move the PRINT position to the column
- specified. It stays on the same line. or, if this would involve
- backspacing, moves on to the next one. Note that the computer
- reduces the column number 'modulo 32' (it divides by 32 and
- takes the remainder); so TAB 33 means the same as TAB 1.
-
- As an example,
-
- PRINT TAB 30;1;TAB 12;"Contents"; AT 3,1;"CHAPTER";TAB
- 24;"page"
-
- is how you might print out the heading of a contents page on
- page 1 of a book
- .
-
- Try running this:
-
- 10 FOR n=8 TO 23
- 20 PRINT TAB 8*n;n;
- 30 NEXT n
-
- This shows what is meant by the TAB numbers being reduced
- modulo 32.
- For a more elegant example, change the 8 in line 20 to a 6.
- Some small points:
-
- (i) These new items are best terminated with semicolons, as we
- have done above. You can use commas (or nothing, at the end of
- the statement), but this means that after having carefully set
- up the PRINT position you immediately move it on again not
- usually terribly useful.
-
- (ii) You cannot print on the bottom two lines (22 and 23) on
- the screen because they are reserved for commands, INPUT data,
- reports and so on. References to 'the bottom line' usually mean
- line 21.
-
- (iii) You can use AT to put the PRINT position even where there
- is already something printed; the old stuff will be obliterated
- when you print more.
-
- Another statement connected with PRINT is CLS. This clears
- the whole screen , something that is also done by CLEAR and
- RUN.
-
- When the printing reaches the bottom of the screen, it starts
- to scroll upwards rather like a typewriter. You can see this if
- you do
-
- CLS: FOR n=1 TO 22: PRINT n: NEXT n
-
- and then do
-
- PRINT 99
-
- a few times.
-
- If the computer is printing out reams and reams of stuff,
- then it takes great care to make sure that nothing is scrolled
- off the top of the screen until you have had a chance to look
- at it properly. You can see this happening if you type
-
- CLS: FOR n=1 TO 100: PRINT n: NEXT n
-
- When it has printed a screen full, it will stop, writing
- scroll? at the bottom of the screen. You can now inspect the
- first 22 numbers at your leisure. When you have finished with
- them, press y (for 'yes') and the computer will give you
- another screen full of numbers. Actually, any key will make the
- computer carry on except n (for 'no'), STOP (SYMBOL SHIFT and
- a), or SPACE (the BREAK key). These will make the computer stop
- running the program with a report D BREAK - CONT repeats.
-
- The INPUT statement can do much more than we have told you so
- far. You have already seen INPUT statements like
-
- INPUT "How old are you?", age
-
- in which the computer prints the caption How old are you? At
- the bottom of the screen, and then you have to type in your
- age.
-
- In fact, an INPUT statement is made up of items and
- separators in exactly the same way as a PRINT statement is, so
- How old are you? and age are both INPUT items. INPUT items are
- generally the same as PRINT items, but there are some very
- important differences.
-
- First, an obvious extra INPUT item is the variable whose
- value you are to type in age in our example above. The rule is
- that if an INPUT item begins with a letter, it must be a
- variable whose value is to be input.
-
- Second, this would seem to mean that you can't print out the
- values of variables as part of a caption; however, you can get
- round this by putting brackets round the variable. Any
- expression that starts with a letter must be enclosed in
- brackets if it is to be printed as part of a caption.
-
- Any kind of PRINT item that is not affected by these rules is
- also an INPUT item. Here is an example to illustrate what's
- going on:
-
- LET my age = INT (RND * 100): INPUT ("I am ";my age; ".
- ");"How old are you?", your age
-
- my age is contained in brackets, so its value gets printed out.
- Your age is not contained in brackets, so you have to type its
- value in.
-
- Everything that an INPUT statement writes goes to the bottom
- part of the screen, which acts somewhat independently of the
- top half. In particular, its lines are numbered relative to the
- top line of the bottom half, even if this has moved up the
- actual television screen (which it does if you type lots and
- lots of INPUT data).
-
- To see how AT works in INPUT statements, try running this:
-
- 10 INPUT "This is line 1.",a$; AT 0,0;"This is line 0.",a$;
- AT 2,0; "This is line 2.",a$; AT 1,0; "This is still line
- 1.",a$
-
- (just press ENTER each time it stops.) When This is line 2. is
- printed, the lower part of the screen moves up to make room for
- it; but the numbering moves up as well, so that the lines of
- text keep their same numbers.
-
- Now try this:
-
- 10 FOR n=0 TO 19: PRINT AT n,0;n;: NEXT n
- 20 INPUT AT 0,0;a$; AT 1,0;a$; AT 2,0;a$; AT 3,0;a$; AT
- 4,0;a$; AT 5,0;a$;
-
- As the lower part of the screen goes up and up, the upper
- part is undisturbed until the lower part threatens to write on
- the same line as the PRINT position. Then the upper part starts
- scrolling up to avoid this.
-
- Another refinement to the INPUT statement that we haven't
- seen yet is called LINE input and is a different way of
- inputting string variables. If you write LINE before the name
- of a string variable to be input, as in
-
- INPUT LINE a$
-
- then the computer will not give you the string quotes that it
- normally does for a string variable, although it will pretend
- to itself that they are there.
- So if you type in
-
- cat
-
- as the INPUT data, a$ will be given the value cat. Because the
- string quotes do not appear on the string, you cannot delete
- them and type in a different sort of string expression for the
- INPUT data. Remember that you cannot use LINE for numeric
- variables.
-
- The control characters CHR$ Z and CHR$ 23 have effects rather
- like AT and TAB. They are rather odd as control characters,
- because whenever one is sent to the television to be printed,
- it must be followed by two more characters that do not have
- their usual effect: they are treated as numbers (their codes)to
- specify the line and column (for AT) or the tab position (for
- TAB). You will almost always find it easier to use AT and TAB
- in the usual way rather than the control characters, but they
- might be useful in some circumstances. The AT control
- character is CHR$ 22. The first character after it specifies
- the line number and the second the column number, so that
-
- PRINT CHR$ 22+CHR$ 1 +CHR$ c;
-
- has exactly the same effect as
-
- PRINT AT 1,c;
-
- This is so even if CHR$ 1 or CHR$ c would normally have a
- different meaning (for instance if c=13); the CHR$ 22 before
- them overrides that.
-
- The TAB control character is CHR$ 23 and the two characters
- after it are used to give a number between 0 and 65535
- specifying the number you would have in a TAB item:
-
- PRINT CHRS 23+CHRS a+CHRS b;
-
- has the same effect as
-
- PRINT TAB a+256*b;
-
- You can use POKE to stop the computer asking you scroll? by
- doing
-
- POKE 23692,255
-
- every so often. After this it will scroll up 255 times before
- stopping with scroll?. As an example, try
-
- 10 FOR n=0 TO 10000
- 20 PRINT n: POKE 23692,255
- 30 NEXT n
-
- and watch everything whizz off the screen!
-
- Exercises
-
- 1. Try this program on some children, to test their
- multiplication tables.
-
- 10 LET m$=" "
- 20 LET a=INT (RND*12)+1: LET b=lNT (RND*12)+1
- 30 INPUT (m$) ' ' "what is ";(a) ";(b);"?";c
- 100 IF c=a-b THEN LET m$="Right.": GO TO 20
- 110 LET m$=''Wrong. Try again.": GO TO 30
-
- If they are perceptive, they might manage to work out that
- they do not have to do the calculation themselves. For
- instance, if the computer asks them to type the answer to 2*3,
- all they have to type in is 2*3.
-
- One way of getting round this is to make them input strings
- instead of numbers. Replace c in line 30 by c$. and in line 100
- by VAL c$, and insert a line
-
-
- 40 IF c$<> STR$ VAL c$ THEN LET m$="Type it properly,
- as a number,":
-
- GO TO 30
-
- That will fool them. After a few more days, however, one of
- them may discover that they can get round this by rubbing out
- the string quotes and typing in STR$ (2*3). To stop up this
- loophole, you can replace c$ in line 30 by LINE c$.
-
-
-
- CHAPTER 16
- Colours
-
- Summary
-
- INK, PAPER, FLASH, BRIGHT, INVERSE, OVER
- BORDER
-
- Run this program:
-
- 10 FOR m=4 TO 1: BRIGHT m
- 20 FOR n=1 TO 14
- 30 FOR c=4 TO 7
- 40 PAPER c: PRINT " ";: REM 4 coloured spaces
- 50 NEXT c: NEXT n: NEXT m
- 60 FOR m=0 TO 1: BRIGHT m: PAPER 7
- 70 FOR c=0 TO 3
- 80 INK c: PRINT c;" ";
- 90 NEXT c: PAPER 0
- 100 FOR c=4 T0 7
- 110 INK c: PRINT c;" ";
- 120 NEXT c: NEXT m
- 130 PAPER 7: INK 0: BRIGHT 0
-
- This shows the eight colours (including white and black) and
- the two levels of brightness that the ZX Spectrum can produce
- on a colour television. (If you r television is black and
- white, then you will just see various shades of grey.) Here is
- a list of them for reference; they are also written over the
- appropriate number keys.
-
- 0 - black
- 1 - blue
- 2 - red
- 3 - purple, or magenta
- 4 - green
- 5 - pale blue, technically called cyan
- 6 - yellow
- 7 - white
-
- On a black and white television, these numbers are in order
- of brightness.
-
- To use these colours properly, you need to understand a bit
- about how the picture is arranged.
-
- The picture is divided up into 768 (24 lines of 32) positions
- where characters can be printed, and each character is printed
- as an 8x8 square of dots like that below for a. This should
- remind you of the user-defined graphics in Chapter 14, where we
- had 0s for the white dots and 1s for the black dots.
-
-
-
- The character position also has associated with it two
- colours: the ink, or foreground colour, which is the colour
- for the black dots in our square, and the paper, or background
- colour, which is used for the white dots. To start off with,
- every position has black ink and white paper so writing appears
- as black on white.
-
- The character position also has a brightness (normal or extra
- bright) and something to say whether it flashes or not -
- flashing is done by swapping the ink and paper colours. This
- can all be coded into numbers, so a character position then has
-
- (i) an 8x8 square of 0s and 1 s to define the shape of the
- character, with 0 for paper and 1 for ink,
-
- (ii) ink and paper colours, each coded into a number between 0
- and 7,
-
- (iii) a brightness - 0 for normal, 1 for extra bright and
-
- (iv) a flash number - 0 for steady, 1 for flashing.
-
- Note that since the ink and paper colours cover a whole
- character position, you cannot possibly have more than two
- colours in a given block of 64 dots. The same goes for the
- brightness and flash number: they refer to the whole character
- position, not individual dots. The colours, brightness and
- flash number at a given position are called attributes.
-
- When you print something on the screen, you change the dot
- pattern at that position; it is less obvious, but still true,
- that you also change the attributes at that position. To start
- off with you do not notice this because everything is printed
- with black ink on white paper (and normal brightness and no
- flashing), but you can vary this with the INK, PAPER, BRIGHT
- and FLASH statements. Try
-
- PAPER 5
-
- and then print a few things: they will all appear on cyan
- paper, because as they are printed the paper colours at the
- positions they occupy are set to cyan (which has code 5).
- The others work the same way, so after
-
- PAPER number between 0 and 7
- INK number between 0 and 7
- BRIGHT 0 or 1 } Think of 0 as off
- or } and 1 as on
- FLASH 0 or 1 }
-
- any printing will set the corresponding attribute at all the
- character positions it uses. Try some of these out. You should
- now be able to see how the program at the beginning worked
- (remember that a space is a character that has INK and PAPER
- the same colour).
-
- There are some more numbers you can use in these statements
- that have less direct effects.
-
- 8 can be used in all four statements, and means 'transparent'
- in the sense that the old attribute shows through. Suppose, for
- instance, that you do
-
- PAPER 8
-
- No character position will ever have its paper colour set to
- 8 because there is no such colour; what happens is that when a
- position is printed on, its paper colour is left the same as it
- was before. INK 8, BRIGHT 8 and FLASH 8 work the same way for
- the other attributes.
-
- 9 can be used only with PAPER and INK, and means 'contrast'.
- The colour (ink or paper) that you use it with is made to
- contrast with the other by being made white if the other is a
- dark colour (black, blue, red or magenta), and black if the
- other is a light colour (green, cyan, yellow or white).
-
- Try this by doing
-
- INK 9: FOR c=0 TO 7: PAPER c: PRINT c: NEXT c
-
- A more impressive display of its power is to run the program
- at the beginning to make coloured stripes, and then doing
-
- INK 9: PAPER 8: PRINT AT 0,8;: FOR n=l TO 1080: PRINT
- n;: NEXT n
-
- The ink colour here is always made to contrast with the old
- paper colour at each position.
-
- Colour television relies on the rather curious fact that the
- human eye can only really see three colours - the primary
- colours, blue, red and green. The other colours are mixtures
- of these. For instance, magenta is made by mixing blue with
- red - which is why its code, 3, is the sum of the codes for
- blue and red.
-
- To see how all eight colours fit together, imagine three
- rectangular spotlights, coloured blue, red and green, shining
- at not quite the same place on a piece of white paper in the
- dark. Where they overlap you will see mixtures of colours, as
- shown by this program (note that ink spaces are obtained by
- using either SHIFT with 8 when in G mode):
-
- 10 BORDER 0: PAPER 0: INK 7: CLS
- 20 FOR a=1 TO 6
- 30 PRINT TAB 6; INK 1; "nnnnnnnnnnnnnnnnnn": REM 18 ink
- squares
- 40 NEXT a
-